#include "Point.h"

template <int DIM>
Point<DIM>::Point() {
	__Coord = new double [DIM];
	__Time = 0;
};

template <int DIM>
Point<DIM>::Point(const double *_x) {
	__Coord = new double [DIM];
	for(int i = 0; i != DIM; i++) {
		__Coord[i] = _x[i];
	}
	__Time = 0;
};

template <int DIM>
Point<DIM>::Point(const Point<DIM> &_p) {
	for(int i = 0; i != DIM; i++) {
		__Coord[i] = _p[i];
	}
	__Time = 0;
};

template <int DIM>
void Point<DIM>::set_point(const double *_x) {
	for(int i = 0; i != DIM; i++) {
		__Coord[i] = _x[i];
	}
};

template <int DIM>
void Point<DIM>::set_time(const double _t) {
	__Time = _t;
};

template <int DIM>
const double Point<DIM>::get_time() const {
	return __Time;
};

template <int DIM>
Point<DIM>::~Point() {
	if(__Coord != NULL) {
		delete [] __Coord;
	}
};

template <int DIM>
const double& Point<DIM>::operator[](int _n) const {
	if(_n < 0 || _n >= DIM) {
		std::cerr << "Out of range!" << std::endl;
		std::exit(-1);
	}
	return __Coord[_n];
};

template <int DIM>
const Point<DIM>& Point<DIM>::operator=(const Point<DIM> &_p) {
	if(this != &_p) {
		for(int i = 0; i != DIM; i++) {
			__Coord[i] = _p[i];
		}
		__Time = _p.get_time();
	}
	return *this;
};

template <int DIM>
std::ostream& operator<<(std::ostream &_os, const Point<DIM> &_p) {
	_os << '[';
	for(int i = 0; i != DIM; i++) {
		_os << _p[i];
		if(i != DIM - 1) {
			_os << ", ";
		}
	}
	_os << ']';
};

template <int DIM>
Point<DIM> operator+(const Point<DIM> &_p1, const Point<DIM> &_p2) {
	Point<DIM> re;
	for(int i = 0; i != DIM; i++) {
		re.__Coord[i] = _p1.__Coord[i] + _p2.__Coord[i]; 
	}
	return re;
};

template <int DIM>
Point<DIM> operator*(const double _k, const Point<DIM> &_p) {
	Point<DIM> re;
	for(int i = 0; i != DIM; i++) {
		re.__Coord[i] = _p.__Coord[i]*_k;
	}
	return re;
}
